using MedicalReportAssistant.Models;
using Newtonsoft.Json;
using System.Text;
using Microsoft.Extensions.Logging;
using System.Net.Http;
using Microsoft.Extensions.Configuration;
using System;
using System.Linq;
using System.Threading.Tasks;
using System.Collections.Generic;

namespace MedicalReportAssistant.Services
{
    public class DeepSeekService : IDeepSeekService
    {
        private readonly HttpClient _httpClient;
        private readonly ILogger<DeepSeekService> _logger;
        private readonly IConfiguration _configuration;
        private readonly string _apiKey;
        private readonly string _apiUrl;
        private readonly string _model;
        private readonly int _maxTokens;
        private readonly double _temperature;

        public DeepSeekService(HttpClient httpClient, ILogger<DeepSeekService> logger, IConfiguration configuration)
        {
            _httpClient = httpClient;
            _logger = logger;
            _configuration = configuration;
            _apiKey = _configuration["DeepSeek:ApiKey"] ?? throw new ArgumentNullException(nameof(configuration), "DeepSeek API Key not configured");
            _apiUrl = _configuration["DeepSeek:ApiUrl"] ?? "https://api.deepseek.com/v1/chat/completions";
            _model = _configuration["DeepSeek:Model"] ?? "deepseek-chat";
            _maxTokens = _configuration.GetValue<int>("DeepSeek:MaxTokens", 2000);
            _temperature = _configuration.GetValue<double>("DeepSeek:Temperature", 0.1);
            _httpClient.DefaultRequestHeaders.Remove("Authorization");
            _httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {_apiKey}");
            _httpClient.Timeout = TimeSpan.FromSeconds(30);
        }

        public async Task<CorrectionResult> CorrectMedicalReportAsync(string originalText)
        {
            ArgumentException.ThrowIfNullOrWhiteSpace(originalText);
            try
            {
                var prompt = BuildCorrectionPrompt(originalText);
                var request = new
                {
                    model = _model,
                    messages = new[]
                    {
                        new { role = "system", content = GetSystemPrompt() },
                        new { role = "user", content = prompt }
                    },
                    temperature = _temperature,
                    max_tokens = _maxTokens
                };

                var json = JsonConvert.SerializeObject(request);
                var content = new StringContent(json, Encoding.UTF8, "application/json");

                _logger.LogInformation("正在发送请求到DeepSeek API...");
                _logger.LogInformation($"请求内容: {json}");

                using var response = await _httpClient.PostAsync(_apiUrl, content);
                var responseContent = await response.Content.ReadAsStringAsync();

                if (!response.IsSuccessStatusCode)
                {
                    _logger.LogError($"DeepSeek API请求失败: {response.StatusCode}, 响应内容: {responseContent}");
                    string userFriendlyMsg = $"API请求失败 ({response.StatusCode})";
                    if (response.StatusCode == System.Net.HttpStatusCode.PaymentRequired || 
                        responseContent.Contains("Insufficient Balance", StringComparison.OrdinalIgnoreCase))
                    {
                        userFriendlyMsg += "：DeepSeek API 余额不足，请充值或更换API密钥。";
                    }
                    else if (responseContent.Contains("invalid_api_key", StringComparison.OrdinalIgnoreCase))
                    {
                        userFriendlyMsg += "：API密钥无效，请检查配置。";
                    }
                    return new CorrectionResult
                    {
                        Success = false,
                        ErrorMessage = $"{userFriendlyMsg}\n原始响应: {responseContent}",
                        OriginalText = originalText,
                        CorrectedText = originalText
                    };
                }

                _logger.LogInformation($"API响应内容: {responseContent}");

                // 新增：检测API响应内容中的error字段
                if (!string.IsNullOrWhiteSpace(responseContent) && responseContent.Contains("\"error\""))
                {
                    try
                    {
                        var errorObj = JsonConvert.DeserializeObject<dynamic>(responseContent);
                        string? errorMsg = errorObj?.error?.message;
                        string? errorCode = errorObj?.error?.code;
                        if (!string.IsNullOrEmpty(errorMsg))
                        {
                            string userFriendlyMsg = $"DeepSeek API请求失败：{errorMsg}";
                            if (errorMsg.Contains("Insufficient Balance", StringComparison.OrdinalIgnoreCase))
                            {
                                userFriendlyMsg += "，请充值或更换API密钥。";
                            }
                            else if (errorCode == "invalid_request_error")
                            {
                                userFriendlyMsg += "（请求参数或账户异常）";
                            }
                            return new CorrectionResult
                            {
                                Success = false,
                                ErrorMessage = $"{userFriendlyMsg}\n原始响应: {responseContent}",
                                OriginalText = originalText,
                                CorrectedText = originalText
                            };
                        }
                    }
                    catch (Exception ex)
                    {
                        _logger.LogError(ex, "解析DeepSeek API错误响应失败");
                    }
                }

                var responseObj = JsonConvert.DeserializeObject<DeepSeekResponse>(responseContent);
                if (responseObj?.Choices?.FirstOrDefault()?.Message?.Content != null)
                {
                    return ParseCorrectionResult(responseObj.Choices[0].Message.Content!, originalText);
                }

                throw new InvalidOperationException("DeepSeek API返回空响应");
            }
            catch (HttpRequestException ex)
            {
                _logger.LogError(ex, "调用DeepSeek API网络错误");
                return new CorrectionResult
                {
                    Success = false,
                    ErrorMessage = $"网络错误: {ex.Message}\n{ex}",
                    OriginalText = originalText,
                    CorrectedText = originalText
                };
            }
            catch (JsonException ex)
            {
                _logger.LogError($"解析DeepSeek API响应失败: {ex.Message}");
                return new CorrectionResult
                {
                    Success = false,
                    ErrorMessage = $"解析响应失败: {ex.Message}",
                    OriginalText = originalText,
                    CorrectedText = originalText
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "调用DeepSeek API失败");
                return new CorrectionResult
                {
                    Success = false,
                    ErrorMessage = $"API调用失败: {ex.Message}\n{ex}",
                    OriginalText = originalText,
                    CorrectedText = originalText
                };
            }
        }

        public async Task<string> GetMedicalTerminologyAsync(string query)
        {
            ArgumentException.ThrowIfNullOrWhiteSpace(query);
            try
            {
                var request = new
                {
                    model = _model,
                    messages = new[]
                    {
                        new { role = "system", content = "你是一个医学影像学专家，请提供准确的医学术语解释。" },
                        new { role = "user", content = $"请解释以下医学术语：{query}" }
                    },
                    temperature = _temperature,
                    max_tokens = 500
                };
                var json = JsonConvert.SerializeObject(request);
                var content = new StringContent(json, Encoding.UTF8, "application/json");
                using var response = await _httpClient.PostAsync(_apiUrl, content);
                response.EnsureSuccessStatusCode();
                var responseContent = await response.Content.ReadAsStringAsync();
                var responseObj = JsonConvert.DeserializeObject<DeepSeekResponse>(responseContent);
                return responseObj?.Choices?.FirstOrDefault()?.Message?.Content ?? "无法获取术语解释";
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取医学术语解释失败");
                return "获取术语解释失败";
            }
        }

        private static string GetSystemPrompt()
        {
            return @"你是一位极其严格和细致的医学影像报告审查专家。你的核心任务是**找出并修正所有问题**，无论多么微小。即使报告看起来完美，你也必须至少提供一条改进建议。

请遵循以下审查步骤：
1. **内容审查**：
   * **重复检测**：
     - 查找并合并内容高度相似或完全重复的句子/段落
     - 识别相邻段落中的重复信息
     - 合并描述相同部位或现象的多处描述
   * **表达规范**：
     - 纠正所有错别字、标点错误和语法问题
     - 确保每个句子都清晰完整
     - 检查句子间的连贯性
   * **术语规范**：
     - 统一医学术语的表达方式
     - 确保专业术语使用准确
     - 检查常见的术语混用问题

2. **逻辑审查**：
   * 检查描述的逻辑顺序是否合理
   * 确保各部分描述之间没有矛盾
   * 验证结论是否与描述相符

3. **格式优化**：
   * 确保段落划分合理
   * 检查标点符号使用是否规范
   * 优化文本结构和排版

4. **表达优化**：
   * 使用更专业、准确的医学表达
   * 改进模糊或不准确的描述
   * 增强文本的可读性

**强制输出要求**：
1. 即使报告看似完美，也必须至少提供一条改进建议，可以是：
   - 格式优化建议
   - 表达改进建议
   - 术语规范化建议
   - 结构优化建议

2. 输出必须是严格的JSON格式：
{
  ""correctedText"": ""【完整的修正后报告文本】"",
  ""corrections"": [
    {
      ""original"": ""【原文片段】"",
      ""corrected"": ""【修改后的片段】"",
      ""reason"": ""【具体的修改原因】"",
      ""type"": ""【逻辑矛盾/术语规范/重复内容/表达优化/格式错误】""
    }
  ],
  ""summary"": ""【本次修改的总体说明】""
}

3. 如果确实找不到明显错误，也要返回格式优化建议：
{
  ""correctedText"": ""【格式优化后的文本】"",
  ""corrections"": [
    {
      ""original"": ""【整体格式】"",
      ""corrected"": ""【优化后的格式示例】"",
      ""reason"": ""建议优化报告格式，增加适当的分段和缩进，提高可读性"",
      ""type"": ""格式错误""
    }
  ],
  ""summary"": ""报告内容准确，建议优化格式以提升可读性""
}";
        }

        private static string BuildCorrectionPrompt(string originalText)
        {
            return $"请对以下医学影像报告进行纠错分析：\n\n{originalText}\n\n请严格按照JSON格式输出结果。";
        }

        private CorrectionResult ParseCorrectionResult(string response, string originalText)
        {
            try
            {
                var startIndex = response.IndexOf('{');
                var endIndex = response.LastIndexOf('}');
                if (startIndex >= 0 && endIndex > startIndex)
                {
                    var jsonText = response[startIndex..(endIndex + 1)];
                    var result = JsonConvert.DeserializeObject<DeepSeekCorrectionResponse>(jsonText);
                    if (result != null)
                    {
                        return new CorrectionResult
                        {
                            Success = true,
                            OriginalText = originalText,
                            CorrectedText = result.CorrectedText ?? originalText,
                            Corrections = result.Corrections?.Select(c => new CorrectionItem
                            {
                                Original = c.Original,
                                Corrected = c.Corrected,
                                Reason = c.Reason,
                                Type = ParseCorrectionType(c.Type)
                            }).ToList() ?? new List<CorrectionItem>(),
                            Summary = result.Summary ?? "纠错完成"
                        };
                    }
                }
                return new CorrectionResult
                {
                    Success = true,
                    OriginalText = originalText,
                    CorrectedText = response,
                    Summary = "AI纠错建议"
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "解析DeepSeek响应失败");
                return new CorrectionResult
                {
                    Success = false,
                    ErrorMessage = "解析响应失败",
                    OriginalText = originalText,
                    CorrectedText = originalText
                };
            }
        }

        private static CorrectionType ParseCorrectionType(string? type)
        {
            return type switch
            {
                "术语规范" => CorrectionType.Terminology,
                "语法错误" => CorrectionType.Grammar,
                "逻辑矛盾" => CorrectionType.Logic,
                "格式规范" => CorrectionType.Format,
                "表达准确性" => CorrectionType.Expression,
                _ => CorrectionType.Expression
            };
        }
    }

    public class DeepSeekResponse
    {
        public List<DeepSeekChoice>? Choices { get; set; }
    }
    public class DeepSeekChoice
    {
        public DeepSeekMessage? Message { get; set; }
    }
    public class DeepSeekMessage
    {
        public string? Content { get; set; }
    }
    public class DeepSeekCorrectionResponse
    {
        public string? CorrectedText { get; set; }
        public List<DeepSeekCorrectionItem>? Corrections { get; set; }
        public string? Summary { get; set; }
    }
    public class DeepSeekCorrectionItem
    {
        public string? Original { get; set; }
        public string? Corrected { get; set; }
        public string? Reason { get; set; }
        public string? Type { get; set; }
    }
} 